#include <cuda_runtime.h>
#include <iostream>
#include <SceneGraph/dynamic_body.h>

namespace PhysLeo {

template<typename T>
DynamicBody<T>::DynamicBody( std::shared_ptr<Integrator<T>> integrator, std::string name) : Node(), body_name_(std::move(name)), sim_data_(), integrator_(std::move(integrator)), renders_()
{
    sim_data_ = std::make_shared<SimData<T>>();
}

template<typename T>
void DynamicBody<T>::addRender(std::shared_ptr<Render<T>>  render)
{
	renders_.push_back(render);
}

template<typename T>
void DynamicBody<T>::initGlResource()
{
	for (auto i = 0u; i < renders_.size(); ++i)
	{
		renders_[i]->init(*sim_data_);
	}
}

template<typename T>
void DynamicBody<T>::draw(CameraInterface  &camera)
{
	for (auto i = 0u; i < renders_.size(); ++i)
	{
		if (renders_[i]->isHidden())continue;
		renders_[i]->draw(camera);
	}
}

template<typename T>
void DynamicBody<T>::initSimulationResource()
{
	integrator_->allocateResource(*sim_data_);
}

template<typename T>
void DynamicBody<T>::run(float dt)
{
	while (dt > max_dt_) {
		integrator_->advanceTime(max_dt_);
		dt -= max_dt_;
	}
	integrator_->advanceTime(dt);

    std::cout << body_name_ << std::endl;
}

template<typename T>
void DynamicBody<T>::transformDrawData()
{
	for (auto i = 0u; i < renders_.size(); ++i)
	{
		renders_[i]->transformToDrawData();
	}
}

template<typename T>
void DynamicBody<T>::updateDrawData()
{
	for (auto i = 0u; i < renders_.size(); ++i)
	{
		renders_[i]->updateDrawData();
	}
}

template class DynamicBody<float>;
template class DynamicBody<double>;

}
